#ifndef SPROXY_H
#define SPROXY_H
#include<vector>
#include<string>
#include<cstdlib>
#include<functional>
#include<iostream>
#include<string>
#include<set>
#include<boost/thread/mutex.hpp>
#include<boost/thread/condition.hpp>
#include"win32.h"
#include"http.hpp"
#include"freeip.hpp"

using namespace std;
struct FetcherConf;
struct ProxyCheckResult;

namespace sproxys {
  extern deque<string> proxys;
  extern set<string> aproxys;
  extern vector<FetcherConf> fetcherconfs;
  extern boost::mutex proxys_mutex;
  extern boost::condition  proxys_cond;
  extern vector<ProxyCheckResult> results;
  extern boost::mutex results_mutex;
  extern int checker_timeout, fetcher_timeout, verbose, ncheckers;
  extern string genpac, pacfile;
  extern string testurl, teststr;
}

struct ProxyCheckResult
{
  double t;
  bool succ;
  string proxy;
  bool operator<(const ProxyCheckResult& r)const;  
};

ostream& operator<<(ostream &os, const ProxyCheckResult&res);

class ProxyChecker
{
  HttpAgent ua;
  HttpRequest req;
  HttpResponse resp;
  string testurl;
  string teststr;
  int timeout;
  int do_check(const string&proxy);
public:
  ProxyChecker(const string& turl, const string& tstr, int to):
    ua(to), req(turl), testurl(turl), teststr(tstr), timeout(to) {
    
  }

  int check(const string& proxy, ProxyCheckResult &r);
    
};

struct FetcherConf
{
  string url;
  string pat;
  string tpl;
  string postdata;
  
  FetcherConf() {}

  FetcherConf(const string&u, const string &p, const string&t, const string&d=""):
    url(u), pat(p), tpl(t), postdata(d) {
  }
};

ostream& operator<<(ostream&os, const FetcherConf&conf);

class ProxysFetcher
{  
  int timeout;
public:
  ProxysFetcher(int to):timeout(to) {}
  
  int fetch(const FetcherConf& conf);
  
};

void  fetch_proxys(void);
void  check_proxys(void);

void readconf(istream &is, int level=0);
void readconf(const string&filename, int level=0);
void parseconf(const string&conf, int level=0);

int timeval_subtract (struct timeval *result,
                      struct timeval *x,
                      struct timeval *y);
  
#endif
